package net.neiquanlib.utils;

import android.content.Context;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;

import org.haitao.common.utils.AppLog;

/**
 * 作者 ： hjb
 * 时间 ： 2016/7/25.
 */

public class BaiduLocationUtils {

    private LocationClient locationClient = null;

    private int runNum = -1;
    private boolean hasEnd;
    static Context mContext;

    private BaiduLocationUtils() {

    }

    private static BaiduLocationUtils locationUtils;

    public static BaiduLocationUtils getInstence(Context applicationContext) {
        mContext = applicationContext;
        if (locationUtils == null) {
            locationUtils = new BaiduLocationUtils();
        }
        return locationUtils;
    }

    private void init() {
        // 初始化设置
        locationClient = new LocationClient(mContext);
        LocationClientOption option = new LocationClientOption();
        option.setOpenGps(true);        //是否打开GPS
        option.setCoorType("bd09ll");   //设置返回值的坐标类型。
        option.setProdName("Locationquickfix"); //设置产品线名称。强烈建议您使用自定义的产品线名称，方便我们以后为您提供更高效准确的定位服务。
        option.setScanSpan(0);    //设置定时定位的时间间隔。单位毫秒
        option.setIsNeedAddress(true);//可选，设置是否需要地址信息，默认不需要
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
        option.setCoorType("bd09ll");//可选，默认gcj02，设置返回的定位结果坐标系，
        option.setIsNeedLocationDescribe(true);//可选，默认false，设置是否需要位置语义化结果，可以在BDLocation.getLocationDescribe里得到，结果类似于“在北京天安门附近”
        option.setIsNeedLocationPoiList(true);//可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
        option.setIgnoreKillProcess(false);//可选，默认true，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认不杀死
        option.SetIgnoreCacheException(false);//可选，默认false，设置是否收集CRASH信息，默认收集
        option.setEnableSimulateGps(false);//可选，默认false，设置是否需要过滤gps仿真结果，默认需要
        locationClient.setLocOption(option);
    }

    /**
     * 请求定位
     * 该方法 如果正在执行 不会重复调用
     * 会直接走 onrequest方法
     */
    public void requestLocation(final LocationCallBck locationCallBck) {
        init();
        runNum = 0;
        locationClient.registerLocationListener(new BDLocationListener() {

            @Override
            public void onReceiveLocation(BDLocation location) {
                // TODO Auto-generated method stub
                if (location == null) {
                    if (locationCallBck != null && !hasEnd) {
                        hasEnd = true;
                        locationCallBck.onFail();
                    }
                    return;
                }
                StringBuffer sb = new StringBuffer(256);
                sb.append("time : ");
                sb.append(location.getTime());
                sb.append("\nerror code : ");
                sb.append(location.getLocType());
                sb.append("\nlatitude : ");
                sb.append(location.getLatitude());
                sb.append("\nlontitude : ");
                sb.append(location.getLongitude());
                sb.append("\nradius : ");
                sb.append(location.getRadius());
                if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
                    sb.append("\nspeed : ");
                    sb.append(location.getSpeed());// 单位：公里每小时
                    sb.append("\nsatellite : ");
                    sb.append(location.getSatelliteNumber());
                    sb.append("\nheight : ");
                    sb.append(location.getAltitude());// 单位：米
                    sb.append("\ndirection : ");
                    sb.append(location.getDirection());
                    sb.append("\naddr : ");
                    sb.append(location.getAddrStr());
                    sb.append("\ndescribe : ");
                    sb.append("gps定位成功");
                    locationClient.stop();
                    if (locationCallBck != null && !hasEnd) {
                        hasEnd = true;
                        locationCallBck.onSuccess(location.getLongitude(), location.getLatitude(), location.getCity() == null ? null : location.getCity().replace("市", ""),location);
                    }
                } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
                    sb.append("\naddr : ");
                    sb.append(location.getCity());
                    //运营商信息
                    sb.append("\noperationers : ");
                    sb.append(location.getOperators());
                    sb.append("\ndescribe : ");
                    sb.append("网络定位成功");
                    locationClient.stop();
                    if (locationCallBck != null && !hasEnd) {
                        hasEnd = true;
                        locationCallBck.onSuccess(location.getLongitude(), location.getLatitude(), location.getCity() == null ? null : location.getCity().replace("市", ""),location);
                    }
                } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果
                    sb.append("\ndescribe : ");
                    sb.append("离线定位成功，离线定位结果也是有效的");
                    locationClient.stop();
                    if (locationCallBck != null && !hasEnd) {
                        hasEnd = true;
                        locationCallBck.onSuccess(location.getLongitude(), location.getLatitude(), location.getCity() == null ? null : location.getCity().replace("市", ""),location);
                    }
                } else if (location.getLocType() == BDLocation.TypeServerError) {
                    sb.append("\ndescribe : ");
                    sb.append("服务端网络定位失败，可以反馈IMEI号和大体定位时间到loc-bugs@baidu.com，会有人追查原因");
                    locationClient.stop();
                    if (locationCallBck != null && !hasEnd) {
                        hasEnd = true;
                        locationCallBck.onFail();
                    }
                } else if (location.getLocType() == BDLocation.TypeNetWorkException) {
                    sb.append("\ndescribe : ");
                    sb.append("网络不同导致定位失败，请检查网络是否通畅");
                    locationClient.stop();
                    if (locationCallBck != null && !hasEnd) {
                        hasEnd = true;
                        locationCallBck.onFail();
                    }
                } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
                    locationClient.stop();
                    sb.append("\ndescribe : ");
                    sb.append("无法获取有效定位依据导致定位失败，一般是由于手机的原因，处于飞行模式下一般会造成这种结果，可以试着重启手机");
                    if (locationCallBck != null && !hasEnd) {
                        hasEnd = true;
                        locationCallBck.onFail();
                    }
                }
                runNum++;
                sb.append("\n检查位置更新次数：");
                sb.append(String.valueOf(runNum));
                AppLog.e(sb.toString());
            }

        });
        locationClient.start();
        locationClient.requestLocation();
    }

    public interface LocationCallBck {
        void onSuccess(double longitude, double latitude, String city,BDLocation location);

        void onFail();
    }
}
